﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.IO;
using EbnfStudio.Controls;
using Scintilla4Net;

namespace EbnfStudio
{
    public partial class MainForm : Form
    {

        /// <summary>
        /// Initalize the form
        /// </summary>
        public MainForm()
        {
            InitializeComponent();
        }


        /// <summary>
        /// Open new text editor
        /// </summary>
        private void OnNew(object sender, EventArgs e)
        {
            AddDoc("UnTitled", new Editor());
        }


        /// <summary>
        /// Open file
        /// </summary>
        /// <param name="filename"></param>
        private void OpenFile(string filename)
        {
            // check if file exits
            if (!File.Exists(filename))
            {
                MessageBox.Show(
                    "File '" + filename + "' not found",
                    "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation
                );
                return;
            }

            // create editor and load file content
            var editor = new Editor();
            editor.Text = File.ReadAllText(filename);
            AddDoc(Path.GetFileName(filename), editor);
        }


        /// <summary>
        /// Add new editor
        /// </summary>
        private void AddDoc(string name, Editor editor)
        {
            // the layout
            var layout = new SplitContainer();
            layout.Dock = DockStyle.Fill;
            layout.Panel1MinSize = 100;
            // the editor
            editor.Dock = DockStyle.Fill;
            editor.Focus();
            editor.Modified += OnVisualGraph;
            layout.Panel1.Controls.Add(editor);
            // canvas
            layout.Panel2.Controls.Add(new ImagePanel());
            // add tab
            AddTab(name, layout);
        }


        /// <summary>
        /// Add new tab
        /// </summary>
        private void AddTab(string name, Control ctrl)
        {
            var tab = new TabPage(name);
            tab.Controls.Add(ctrl);
            tab.BorderStyle = BorderStyle.FixedSingle;
            ContentTabs.Controls.Add(tab);
            ContentTabs.SelectedTab = tab;
            ContentTabs.Visible = true;
            // ctrl.Focus();
        }


        /// <summary>
        /// Generate visual graph from the source
        /// </summary>
        private void OnVisualGraph(object sender, EventArgs e)
        {
            // no tabs
            if (ContentTabs.TabCount == 0) return;

            // get the control
            // var current = ContentTabs.SelectedTab.Controls[0];
            var layout = (SplitContainer)ContentTabs.SelectedTab.Controls[0];
            var current = layout.Panel1.Controls[0];

            // not a scintilla control
            if (!(current is Editor)) return;
            var editor = (Editor)current;
            // var editor = (Editor)layout.Panel1.Controls[0];
            
            // parse
            // var ast = parser.Parse(editor.Text);
            var parser = editor.parser;
            var ast = parser.Tree;

            // there were errors
            if (parser.Output.Length > 0)
            {
                Console.Text += parser.Output;
                return;
            }

            if (ast == null) return;
            
            // create the image
            var visualizer = new GraphVisual(ast);
            if (visualizer.Bitmap == null) return;

            // var canvas = new ImagePanel();
            // canvas.Image = visualizer.Bitmap;
            // AddTab(ContentTabs.SelectedTab.Text + " - diagram", canvas);
            var canvas = (ImagePanel)layout.Panel2.Controls[0];
            canvas.Image = visualizer.Bitmap;
            
        }


        /// <summary>
        /// Show open file dialog
        /// </summary>
        private void OnOpen(object sender, EventArgs e)
        {
            fileDialog.ShowDialog();

            foreach (var file in fileDialog.FileNames)
            {
                this.OpenFile(file);
            }
        }
    }
}
